# -*- coding: utf-8 -*-
'''
# Created by Haoliyou at 2018/4/27
'''
__author__='Haoliyou'
import time
import json
import pymysql
import hashlib
import urllib
from urllib import parse, request

class BaiduAPI(object):
    """
    百度地图API
    doc :http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi
    """
    def __init__(self, aktype='self' , is_sn=None):
        '''
        '''
        self.BaseUrl = 'http://api.map.baidu.com'
        self.Ak      = 'key1' #''
        self.is_sn   = is_sn
        self.output  = 'json' #输出格式为json或者xml
        self.timestamp = time.localtime()
        if aktype=='self':
            self.Ak = 'key1'
        elif aktype=='comp2':
            self.Ak = 'key2'

    def coordinate_convert(self, coords='',froms=3, to=5):
        '''
        其他坐标转百度坐标
        doc :http://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition
        :param coords: 需转换的源坐标，多组坐标以“；”分隔（经度，纬度）最多40个
        :param froms: 源坐标类型：1：GPS设备获取的角度坐标，wgs84坐标;
                                2：GPS获取的米制坐标、sogou地图所用坐标;
                                3：google地图、soso地图、aliyun地图、mapabc地图和amap地图所用坐标，国测局（gcj02）坐标
        :param to:目标坐标类型：3：国测局（gcj02）坐标;
                                4：3中对应的米制坐标;
                                5：bd09ll(百度经纬度坐标);
                                6：bd09mc(百度米制经纬度坐标)
        :return:
        '''
        b_location = {}
        cor_list = coords.split(';')
        '''
        坐标个数超过40个分批处理
        '''
        if len(cor_list)>40:
            li_locat = []
            cor2_list = [cor_list[i:i + 40] for i in range(0, len(cor_list), 40)]
            for co in cor2_list:
                cos = ';'.join(co)
                blocation = self.toomuchcoords(coords=cos,froms=3, to=5)
                result = blocation.get('result', [])
                if len(result) > 0:
                    for r in result:
                        li_locat.append(str(r['x']) + ',' + str(r['y']))
                else:
                    print("toomuch in for info:{0} ".format(blocation))
            if len(li_locat)>0:
                b_road_location = ';'.join(li_locat)
                b_location['status'] = 0
                b_location['data'] = b_road_location
            else:
                b_location['status'] = 1
                b_location['info'] = b_location
        else:
            blocation = self.toomuchcoords(coords=coords,froms=froms, to=to)
            result = blocation.get('result', [])
            if len(result) > 0:
                li_locat = []
                for r in result:
                    li_locat.append(str(r['x']) + ',' + str(r['y']))
                b_road_location = ';'.join(li_locat)
                b_location['status'] = 0
                b_location['data'] = b_road_location
            else:
                b_location['status'] = 1
                b_location['info'] = b_location

        return b_location

    def toomuchcoords(self,coords='',froms=3, to=5):

        au = '/geoconv/v1/'
        pram = {
            'coords': coords,
            'from': froms,
            'to': to,
            'output': self.output,
            'ak': self.Ak
        }
        return json.loads(self.get(self.BaseUrl, au, pram))

    def ASDASearch(self, query=None, region=None, tag=None, city_limit=True, scope=1, filter=None, coord_type=2, page_size=20, page_num=0):
        '''
        行政区划区域检索: Administrative division area search.
        :param query: 检索关键字。周边检索和矩形区域内检索支持多个关键字并集检索，不同关键字间以$符号分隔，最多支持10个关键字检索。如:”银行$酒店”
        :param region: 检索行政区划区域（增加区域内数据召回权重，如需严格限制召回数据在区域内，请搭配使用city_limit参数），可输入行政区划名或对应cityCode
        :param tag: 检索分类，与q组合进行检索，多个分类以"美食 ,酒店 "分隔, readeto : http://lbsyun.baidu.com/index.php?title=lbscloud/poitags
        :param city_limit: 区域数据召回限制，为true时，仅召回region对应区域内数据。
        :param scope: 检索结果详细程度。取值为1 或空，则返回基本信息；取值为2，返回检索POI详细信息
        :param filter: 检索过滤条件。当scope取值为2时，可以设置filter进行排序。
                industry_type：行业类型，注意：设置该字段可提高检索速度和过滤精度，取值有： hotel（宾馆）；cater（餐饮）；life（生活娱乐）
                sort_name：排序字段，根据industry_type字段的值而定。
                1、industry_type为hotel时，sort_name取值有： default（默认）；price（价格）；total_score（好评）；level（星级）；health_score（卫生）；distance（距离排序，只有周边检索有效）
                2、industry_type为cater时，sort_name取值有： default（默认）；taste_rating（口味）；price（价格）；overall_rating（好评）；service_rating（服务）；distance（距离排序，只有周边检索有效）
                3、industry_type为life时，sort_name取值有： default（默认）；price（价格）；overall_rating（好评）；comment_num（服务）；distance（距离排序，只有周边检索有效）
                sort_rule：排序规则：0（从高到低），1（从低到高）
                price_section：价格区间
                groupon：是否有团购：1（有），0（无）
                discount：是否有打折：1（有），0（无）
        :param coord_type: 坐标类型，1（wgs84ll即GPS经纬度），2（gcj02ll即国测局经纬度坐标），3（bd09ll即百度经纬度坐标），4（bd09mc即百度米制坐标）
        :param page_size: 单次召回POI数量，默认为10条记录，最大返回20条。多关键字检索时，返回的记录数为关键字个数*page_size。
        :param page_num: 分页页码，默认为0,0代表第一页，1代表第二页，以此类推。常与page_size搭配使用。
        :return:
        '''
        au = '/place/v2/search/'
        pram = {
            'query': query,
            'region': region,
            'tag':tag,
            'page_size': page_size,
            'page_num':page_num,
            'output': self.output,
            'ak': self.Ak
        }
        return json.loads(self.get(self.BaseUrl , au, pram))

    def AroundSearch(self, location=None, region=None, query='', tag='', radius=1000, offset=200, page=1, scope=2):
        """
        周边检索
        :param location: *周边检索中心点经纬度，不支持多个点
        :param region: *周边检索行政区划区域检索
        :param query: *检索关键字。
        :param tag: 检索分类，与q组合进行检索，多个分类以","分隔
        :param radius: 周边检索半径，单位为米。
        :param offset: 单次召回POI数量，默认为10条记录，最大返回20条。
        :param page: 分页页码，默认为0,0代表第一页，1代表第二页，以此类推
        :param scope: 检索结果详细程度。取值为1 或空，则返回基本信息；取值为2，返回检索POI详细信息
        :return:
        """
        au = '/place/v2/search'
        pram = {
            'query': query,
            'tag': tag,
            'radius': radius,
            'page_size': offset,
            'page_num': page,
            'scope': scope,
            'ak': self.Ak,
            'output': self.output,
        }
        # 判断是以 行政区划区域检索/经纬度周边检索
        if location:
            # 经纬度周边检索
            pram['location'] = location
        elif region:
            # 行政区划区域检索
            pram['region'] = region
        else:
            return {'status':500,'msg':'no location or region'}

        return json.loads(self.get(self.BaseUrl, au, pram))

    def GeoCoderSearh(self, address='', city='', ret_coordtype='', output='json',callback=None):
        '''
        地理编码
        doc :http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding
        :param address:
        :param city:
        :param ret_coordtype:
        :param output:
        :param callback:
        :return:
        '''
        au = '/geocoder/v2/'
        pram = {
            'address': address,
            'city': city,
            'output': self.output,
            'ak': self.Ak
        }
        return json.loads(self.get(self.BaseUrl , au, pram))

    def NoGeoCoderSearh(self, location,pois=1,radius=1000,extensions_road=True,latest_admin=True):
        '''
        逆地理编码
        doc : http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding-abroad
        :param location: *****根据经纬度坐标获取地址。float 38.76623,116.43213 , lat<纬度>,lng<经度>
        :param pois: 是否召回传入坐标周边的poi，0为不召回，1为召回
        :param radius: poi召回半径，允许设置区间为0-1000米，超过1000米按1000米召回。
        :param extensions_road: 当取值为true时，召回坐标周围最近的3条道路数据。区别于行政区划中的street参数（street参数为行政区划中的街道，和普通道路不对应）
        :param latest_admin: 是否访问最新版行政区划数据（仅对中国数据生效），1（访问），0（不访问）
        :return:
        '''
        # **特别注意 location是维度,经度

        # location


        au = '/geocoder/v2/'
        pram = {
            'location': location,
            'pois': pois,
            'radius': radius,
            'extensions_road': extensions_road,
            'latest_admin': latest_admin,
            'output': self.output,
            'ak': self.Ak
        }
        return json.loads(self.get(self.BaseUrl, au, pram))

    def get(self, url, au, prame):
        '''
        get 请求：
        :param url: url = 'http://192.168.199.1:8000/mainsugar/loginGET/'
        :param au:
        :param prame: 传参数 如:{'user': 'admin', 'password': 'admin'}
        :return:
        '''
        try:
            # 输出内容:user=admin&password=admin
            prames = parse.urlencode(prame)
            if self.is_sn:
                prame['sn'] = self.make_sn("%s%s%s"%(au,'?', prames))
                prames = parse.urlencode(prame)
        except Exception as e:
            print("prame Exception :%s" % (e,))
            return self.get(url, au, prame)

        headers = {"Connection": "keep-alive",
                   "Cache-Control": "max-age=0",
                   "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36",
                   "Accept": "text/html,application/xhtml+xml,application/xml;",
                   "Accept-Language": "zh-CN",
                   #"Host": "101.201.59.236:8081",
                   #"Origin": "http://101.201.59.236:8081",
                   #"Referer": "http://101.201.59.236:8081/ccuas/privilege/loginAction.do?reqCode=logout"
                   }
        try:
            req = request.Request(url='%s%s%s%s' % (url, au,'?', prames), headers=headers)
            res = request.urlopen(req)
            res = res.read()
        except Exception as e:
            print("get request Exception :%s" % (e,))
            return '{}'
        #print(res.decode('utf-8'))
        # 输出内容(python3默认获取到的是16进制'bytes'类型数据 Unicode编码，如果如需可读输出则需decode解码成对应编码):b'\xe7\x99\xbb\xe5\xbd\x95\xe6\x88\x90\xe5\x8a\x9f'
        return res.decode('utf-8')

    def make_sn(self, queryStr):
        '''
        生成sn
        :param queryStr:
        :return:
        '''
        # 以get请求为例http://api.map.baidu.com/geocoder/v2/?address=百度大厦&output=json&ak=yourak
        # queryStr = '/geocoder/v2/?address=百度大厦&output=json&ak=yourak'

        # 对queryStr进行转码，safe内的保留字符不转换
        encodedStr = urllib.quote(queryStr, safe="/:=&?#+!$,;'@()*[]")

        # 在最后直接追加上yoursk
        rawStr = encodedStr + self.Ak

        # md5计算出的sn值7de5a22212ffaa9e326444c75a58f9a0
        # 最终合法请求url是http://api.map.baidu.com/geocoder/v2/?address=百度大厦&output=json&ak=yourak&sn=7de5a22212ffaa9e326444c75a58f9a0
        # print(hashlib.md5(urllib.quote_plus(rawStr)).hexdigest())
        return hashlib.md5(urllib.quote_plus(rawStr)).hexdigest()


class GaoDeAPI(object):
    """
    高德地图API
    doc :http://lbs.amap.com/api/webservice/guide/api/search/
    """
    def __init__(self, ak='one'):

        #
        self.BaseUrl = 'http://restapi.amap.com/v3/'
        self.Ak = 'key1' # company_ak
        self.sig = '' # 数字签名
        self.output = 'json'  # 输出格式为json或者xml
        if ak =='one': # 余威的
            self.Ak = 'key1'
        elif ak == 'two':
            self.Ak = 'key2'

    def coordinate_convert(self, locations='',coordsys='baidu'):
        '''
        其他坐标转高德坐标
        doc: http://lbs.amap.com/api/webservice/guide/api/convert
        :param locations: 经度和纬度用","分割，经度在前，纬度在后，经纬度小数点后不得超过6位。多个坐标对之间用”|”进行分隔最多支持40对坐标。
        :param coordsys: 可选值： gps; mapbar; baidu; autonavi(不进行转换)
        :return:
        '''
        au = 'assistant/coordinate/convert'
        pram = {
            'key': self.Ak,
            'locations': locations,
            'coordsys': coordsys,
            'output': self.output,
        }
        return json.loads(self.get(self.BaseUrl + au, pram))

    def TextSearch(self,keywords=None,types='',city=None,children=1,offset=20,page=1,extensions='all'):
        """
        关键字搜索
        http://restapi.amap.com/v3/place/text?key=您的key&keywords=北京大学&types=高等院校&city=北京&children=1&offset=20&page=1&extensions=all
        :param keywords: 查询关键词
        :param types:查询POI类型
        :param city: 城市名，可填：城市中文、中文全拼、citycode或adcode
        :param children: 按照层级展示子POI数据
        :param offset: 每页记录数据
        :param page: 当前页数
        :param extensions: 返回结果控制all/base
        :param citylimit: 仅返回指定城市数据
        :return:
        """
        au = 'place/text'
        pram = {
            'keywords': keywords,
            'city': city,
            'types': types,
            'children':children,
            'offset':offset,
            'page':page,
            'extensions':extensions,
            'key': self.Ak,
            'output': self.output,
        }
        return json.loads(self.get(self.BaseUrl + au, pram))

    def AroundSearch(self,location=None,keywords=None,types='',radius=1000,offset=20,page=1,extensions='all'):
        """
        周边搜索
        http://restapi.amap.com/v3/place/around?key=您的key&location=104.041069,30.636128&keywords=肯德基&types=服务&radius=1000&offset=20&page=1&extensions=all

        :param location: 中心点坐标
        :param keywords: 查询关键词 .规则： 多个关键字用“|”分割
        :param types: 查询POI类型 .多个类型用“|”分割；
                        可选值：分类代码 或 汉字 （若用汉字，请严格按照附件之中的汉字填写）
                        分类代码由六位数字组成，一共分为三个部分，前两个数字代表大类；中间两个数字代表中类；最后两个数字代表小类。
                        若指定了某个大类，则所属的中类、小类都会被显示。
        :param radius: 查询POI类型
        :param offset: 每页记录数据
        :param page: 当前页数
        :param extensions: 返回结果控制
        :return:
        {'status': '1', 'count': '3', 'info': 'OK', 'infocode': '10000', 'suggestion': {'keywords': [], 'cities': []},
        'pois': [{'id': 'B001C7TSC0', 'tag': '奥尔良烤鸡翅,', 'name': '肯德基(罗马店)', 'type': '餐饮服务;快餐厅;肯德基',
        'typecode': '050301', 'biz_type': 'diner', 'address': '高升桥东路2-6罗马假日广场C座',
        'location': '104.041637,30.637074', 'tel': '028-85108569', 'postcode': [], 'website': 'www.kfc.com.cn',
        'email': [], 'pcode': '510000', 'pname': '四川省', 'citycode': '028', 'cityname': '成都市', 'adcode': '510107',
        'adname': '武侯区', 'importance': [], 'shopid': [], 'shopinfo': '0', 'poiweight': [], 'gridcode': '4504706310',
        'distance': '118', 'navi_poiid': 'H48F017017_373216', 'entr_location': '104.041547,30.636943',
        'exit_location': [], 'match': '0', 'recommend': '0', 'timestamp': [], 'alias': [], 'indoor_map': '0',
        'indoor_data': {'cpid': [], 'floor': [], 'truefloor': []}, 'groupbuy_num': '0', 'business_area': '高升桥',
        'discount_num': '0', 'biz_ext': {'rating': '3.5', 'cost': '30.00', 'meal_ordering': '0'}, 'event': [],
        'photos': [{'title': [], 'url': 'http://store.is.autonavi.com/showpic/23107a49f964cc42f41a9c790044e382'},
        {'title': [], 'url': 'http://store.is.autonavi.com/showpic/807294cbf8e4e92067d5fdab4ab2e131'},
        {'title': [], 'url': 'http://store.is.autonavi.com/showpic/3c49f12c310a0f1fb4594316d1a0fe7d'}],
        'children': []}, {'id': 'B001C7WHRD', 'tag': '草莓圣代,雪顶爱尔兰咖啡 ', 'name': '肯德基(华达店)',
        'type': '餐饮服务;快餐厅;肯德基', 'typecode': '050301', 'biz_type': 'diner',
        'address': '武候大街266号华达商厦1-2层', 'location': '104.042027,30.641293',
        'tel': '028-85591150;028-85567277;4008823823', 'postcode': [], 'website': 'www.kfc.com.cn', 'email': [],
        'pcode': '510000', 'pname': '四川省', 'citycode': '028', 'cityname': '成都市', 'adcode': '510107',
        'adname': '武侯区', 'importance': [], 'shopid': [], 'shopinfo': '0', 'poiweight': [], 'gridcode': '4504706321',
        'distance': '582', 'navi_poiid': 'H48F017017_253347', 'entr_location': '104.041723,30.641167',
        'exit_location': [], 'match': '0', 'recommend': '0', 'timestamp': [], 'alias': [], 'indoor_map': '0',
        'indoor_data': {'cpid': [], 'floor': [], 'truefloor': []}, 'groupbuy_num': '0', 'business_area': [],
        'discount_num': '0', 'biz_ext': {'rating': '3.5', 'cost': '24.00', 'meal_ordering': '0'}, 'event': [],
        'photos': [{'title': [], 'url': 'http://store.is.autonavi.com/showpic/3d178453714cb6feffa1f5ec00328719'},
        {'title': [], 'url': 'http://store.is.autonavi.com/showpic/e4f67f8f6069e7f970ece61c13bae5b9'},
        {'title': [], 'url': 'http://store.is.autonavi.com/showpic/543cd200f0e6a45e3cf6f8377924d434'}], 'children': []},
        {'id': 'B001C92226', 'tag': '撕猪肉卷,雪顶焦糖布丁', 'name': '肯德基(莱蒙都会店)', 'type': '餐饮服务;快餐厅;肯德基',
        'typecode': '050301', 'biz_type': 'diner', 'address': '二环路南四段51号莱蒙都会4栋1-2层',
        'location': '104.034257,30.631622', 'tel': '028-87441029;028-87441595', 'postcode': [], 'website': [],
        'email': [], 'pcode': '510000', 'pname': '四川省', 'citycode': '028', 'cityname': '成都市', 'adcode': '510107',
        'adname': '武侯区', 'importance': [], 'shopid': [], 'shopinfo': '0', 'poiweight': [], 'gridcode': '4504705222',
        'distance': '823', 'navi_poiid': 'H48F017017_191918', 'entr_location': [], 'exit_location': [], 'match': '0',
        'recommend': '0', 'timestamp': [], 'alias': [], 'indoor_map': '0', 'indoor_data': {'cpid': [], 'floor': [],
        'truefloor': []}, 'groupbuy_num': '0', 'business_area': [], 'discount_num': '0', 'biz_ext':
        {'rating': '3.5', 'cost': '31.00', 'meal_ordering': '0'}, 'event': [],
        'photos': [{'title': [], 'url': 'http://store.is.autonavi.com/showpic/cf64ea8e22533b4bba864a3b10c322fb'},
        {'title': [], 'url': 'http://store.is.autonavi.com/showpic/b0e5e3d1983f52f96e2beb7f444d0675'},
        {'title': [], 'url': 'http://store.is.autonavi.com/showpic/35bae73a2ac9de7171a68bfc32b5a1a3'}], 'children': []}]}
        """
        au = 'place/around'
        pram = {
            'location':location,
            'keywords': keywords,
            'types': types,
            'radius':radius,
            'offset': offset,
            'page': page,
            'extensions': extensions,
            'key': self.Ak,
            'output': self.output,
        }
        return json.loads(self.get(self.BaseUrl + au, pram))

    def GeoSearch(self,address='', city='',batch='false'):
        '''
        地理编码 API
        根据地址 城市，返回省市区，坐标，区号，全地址
        doc:http://lbs.amap.com/api/webservice/guide/api/georegeo
        :param address: 结构化地址信息;如果需要解析多个地址的话，请用"|"进行间隔，并且将 batch 参数设置为 true，最多支持 10 个地址进进行"|"分割形式的请求。
        :param city: 指定查询的城市;指定城市的中文（如北京）、指定城市的中文全拼（beijing）、citycode（010）、adcode（110000）。当指定城市查询内容为空时，会进行全国范围内的地址转换检索。
        :param batch: fasle
        :return:
        '''
        au = 'geocode/geo'
        pram = {
            'address': address,
            'city': city,
            'batch': batch,
            'key': self.Ak,
            'output': self.output,
        }
        return json.loads(self.get(self.BaseUrl + au, pram))

    def RegeoSearch(self, location='', keywords='', radius=1000, extensions='all', batch='false', roadlevel=0, homeorcorp=2):
        '''
        逆地理编码 API
        根据经纬度/类型，返回周围地标，省市区，坐标，区号，全地址
        doc:http://lbs.amap.com/api/webservice/guide/api/georegeo
        :param location: 经纬度坐标;最多支持20个坐标点;多个点之间用"|"分割。
        :param poitype: 支持传入POI TYPECODE及名称；支持传入多个POI类型，多值间用“|”分隔
        :param radius: 查询POI的半径范围。取值范围：0~3000,单位：米
        :param extensions: 参数默认取值是 base，也就是返回基本地址信息；
                        参数取值为 all 时会返回基本地址信息、附近 POI 内容、道路信息以及道路交叉口信息。
        :param batch: 批量查询控制;batch 参数设置为 true 时进行批量查询操作
        :param roadlevel: 道路等级;0时，显示所有道路; 1时，过滤非主干道路，仅输出主干道路数据
        :param homeorcorp: 是否优化POI返回顺序
        :return:
        '''
        au = 'geocode/regeo'
        pram = {
            'location': location,
            'poitype': keywords,
            'radius': radius,
            'extensions': extensions,
            'batch': batch,
            'roadlevel': roadlevel,
            'homeorcorp': homeorcorp,
            'key': self.Ak,
            'output': self.output,
        }
        return json.loads(self.get(self.BaseUrl + au, pram))

    def DistrictSearch(self,keywords='',subdistrict=3, extensions='all'):
        '''
        行政区域查询
        :param keywords: 规则：只支持单个关键词语搜索关键词支持：行政区名称、citycode、adcode
                        例如，在subdistrict=2，搜索省份（例如山东），能够显示市（例如济南），区（例如历下区）
        :param subdistrict: 规则：设置显示下级行政区级数（行政区级别包括：国家、省/直辖市、市、区/县4个级别）
                            可选值：0、1、2、3
                            0：不返回下级行政区；
                            1：返回下一级行政区；
                            2：返回下两级行政区；
                            3：返回下三级行政区；
        :param extensions: 此项控制行政区信息中返回行政区边界坐标点； 可选值：base、all;
                            base:不返回行政区边界坐标点；
                            all:只返回当前查询district的边界值，不返回子节点的边界值；
        :return:
        '''
        au = 'config/district'
        pram = {
            'keywords': keywords,
            'subdistrict': subdistrict,
            'extensions': extensions,
            'key': self.Ak,
            'output': self.output,
        }
        return json.loads(self.get(self.BaseUrl + au, pram))

    def get(self,url,param):
        """
        :param url:
        :param param:
        :return:
        """
        try:
            # 输出内容:user=admin&password=admin
            prame = parse.urlencode(param)
        except Exception as e:
            print("param Exception :%s" % (e,))
            return self.get(url,param)

        headers = {"Connection": "keep-alive",
                   "Cache-Control": "max-age=0",
                   "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36",
                   "Accept": "text/html,application/xhtml+xml,application/xml;",
                   "Accept-Language": "zh-CN",
                   #"Host": "101.201.59.236:8081",
                   #"Origin": "http://101.201.59.236:8081",
                   #"Referer": "http://101.201.59.236:8081/ccuas/privilege/loginAction.do?reqCode=logout"
                   }
        try:
            req = request.Request(url='%s%s%s' % (url, '?', prame), headers=headers)
            res = request.urlopen(req)
            res = res.read()
        except Exception as e:
            print("get request Exception :%s" % (e,))
            return '{}'
        #print(res.decode('utf-8'))
        # 输出内容(python3默认获取到的是16进制'bytes'类型数据 Unicode编码，如果如需可读输出则需decode解码成对应编码):b'\xe7\x99\xbb\xe5\xbd\x95\xe6\x88\x90\xe5\x8a\x9f'
        return res.decode('utf-8')


class MapToolsApi(object):
    def __init__(self, param=None, cityname=''):
        self.param = param
        self.conn = pymysql.connect(host=" ", user="",
                                    passwd="", db="", charset="utf8")
        self.cursor = self.conn.cursor()
        self.cityname = cityname
        #
        # 
        sql = '''
            select area,yxcenter_name,yxcenter_id,jwdu from cdcm_b_marketing_center
        '''
        # 
        sql_dz = '''
		select area,yxcenter_name,yxcenter_code,jwdu,business_department,grid_name, id from dzcm_b_marketing_center
                '''
        if cityname=='达州':
            self.cursor.execute(sql_dz)
        else:
            self.cursor.execute(sql)
        self.center_data = self.cursor.fetchall()

    def IsPtInPoly(self, aLon, aLat, pointList):
        '''''
        判断一个指定的经纬坐标是否落在一个多边形区域内
        :param aLon: double 经度
        :param aLat: double 纬度
        :param pointList: list [(lon, lat)...] 多边形点的顺序需根据顺时针或逆时针，不能乱
        '''
        aLon = float(aLon)
        aLat = float(aLat)
        iSum = 0
        iCount = len(pointList)

        if (iCount < 3):
            return False
        for i in range(iCount):
            pLon1 = float(pointList[i][0])
            pLat1 = float(pointList[i][1])
            if (i == (iCount-1)):
                pLon2 = float(pointList[0][0])
                pLat2 = float(pointList[0][1])
            else:
                pLon2 = float(pointList[i + 1][0])
                pLat2 = float(pointList[i + 1][1])
            if ((aLat >= pLat1) and (aLat < pLat2)) or ((aLat >= pLat2) and (aLat < pLat1)):
                if (abs(pLat1 - pLat2) > 0):
                    pLon = pLon1 - ((pLon1 - pLon2) * (pLat1 - aLat)) / (pLat1 - pLat2);
                    if (pLon < aLon):
                        iSum += 1
        if (iSum % 2 != 0):
            return True
        else:
            return False

    def is_yxcenter(self, aLon, aLat):
        '''
        判断坐标是否在网格内
        :param aLon: 经度
        :param aLat: 维度
        :return:
        '''

        yxcenter_dic = []
        if len(self.center_data) > 0:
            # 格式化jwdu
            for li in self.center_data:
                #area,yxcenter_name,yxcenter_id,jwdu,  fenju, yingyebu
                lis = {}
                lis['yxcenter_area'] = li[0]
                lis['yxcenter_name'] = li[1]
                lis['yxcenter_id'] = li[2]
                if self.cityname == '达州':
                    lis['business_department'] = li[4]
                    lis['grid_name'] = li[5]
                    lis['grid_id'] = li[6]
                jwdu = li[3]
                #104.058684,30.640646;104.058755,30.640802;104.045065,30.619578;104.03504,30.624643;104.040825,30.634028;104.044814,30.635457;104.050671,30.64453;
                jwdu_list = jwdu.split(';')
                jwdu_dic = []
                for i in jwdu_list:
                    if len(i)>6:
                        aLon_aLat = i.split(',')
                        jwdu_dic.append(aLon_aLat)
                #[(lon, lat)...]
                lis['jwdu'] = jwdu_dic
                yxcenter_dic.append(lis)

        # 取得坐标，判断
        for yx in yxcenter_dic:
            jwdu = yx['jwdu']
            if self.IsPtInPoly(aLon, aLat,jwdu):
                return yx
        else:
            print("该坐标没有在任何范围内：%s,%s"% (aLon, aLat))
            return False


if __name__ == '__main__':
    print('=======')
    baidu = BaiduAPI()
    # baidu_back = baidu.ASDASearch('成都果粒公寓古大圣慈寺分店', '成都市')
    # baidu_back = baidu.GeoCoderSearh('成都果粒公寓古大圣慈寺分店', '成都市')

    gaode = GaoDeAPI()
    baidu_back = gaode.RegeoSearch(location='104.040135,30.637876',keywords='写字楼',)

    print(baidu_back)
    baidu_back = baidu_back

    print(baidu_back.get("status", -1))
    print(baidu_back.get('results', []))
    results = baidu_back.get('results', [])
    if len(results) > 0:
        print(results[0])
    else:
        print("无")
    # location
    # telephone
